package com.sinosoft.ci.patch.svn;

import java.io.File;
import java.io.FileFilter;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;

import com.sinosoft.ci.patch.SrcEntryToPatchEntryConvertor;

/**
 * 国联项目组，核心系统源码到补丁包条目转换器。
 * 
 * @author 韩朝祥
 *
 */
public class GuoLianLisSrcEntryToPatchEntryConvertor implements
		SrcEntryToPatchEntryConvertor {
	private static final Logger logger = Logger.getLogger(GuoLianLisSrcEntryToPatchEntryConvertor.class);
	private File appRootDir;
	private File classesDir;
	
	public GuoLianLisSrcEntryToPatchEntryConvertor(File appRootDir){
		if(null == appRootDir){
			throw new NullPointerException("目录不能为 null！");
		}
		
		if(!appRootDir.exists() || !appRootDir.isDirectory()){
			throw new IllegalArgumentException(String.format("%s 不是一个合法目录！", appRootDir.getAbsolutePath()));
		}
		this.appRootDir = appRootDir;
		
		File classesDir = new File(appRootDir,"WEB-INF/classes");
		if(!classesDir.exists() || !classesDir.isDirectory()){
			throw new IllegalArgumentException(String.format("%s 不是一个合法目录！", classesDir.getAbsolutePath()));
		}
		this.classesDir = classesDir;
	}

	@Override
	public String[] convert(String srcEntry) {
		if(srcEntry.toLowerCase().startsWith("java_other/src/")){
			String entry = srcEntry.substring("java_other/src/".length());
			return convertClassPathEntry(entry);
		}else if(srcEntry.toLowerCase().startsWith("java/src/")){
			String entry = srcEntry.substring("java/src/".length());
			return convertClassPathEntry(entry);
		}else if(srcEntry.toLowerCase().startsWith("java_schema/src/")){
			String entry = srcEntry.substring("java_schema/src/".length());
			return convertClassPathEntry(entry);
		}else if(srcEntry.toLowerCase().startsWith("ui/")){
			String entry = srcEntry.substring("ui/".length());
			return convertUIEntry(entry);
		}
		
		logger.warn(String.format("源码条目 %s 没有算出对应的补丁条目！", srcEntry));
		return new String[]{};
	}
	
	private String[] convertClassPathEntry(String entry){
		if(null == entry){
			throw new IllegalArgumentException(entry + "不是一个合法的条目！");
		}
		if(entry.toLowerCase().endsWith(".java")){
			return convertJavaEntry(entry);
		}
		entry = trimSep(entry);
		return new String[]{"WEB-INF/classes/" + entry};
	}
	
	private String[] convertJavaEntry(String javaEntry){
		if(null == javaEntry || !javaEntry.toLowerCase().endsWith(".java")){
			throw new IllegalArgumentException(javaEntry + " 不是一个合法的 java 条目！");
		}
		javaEntry = trimSep(javaEntry);
		
		String[] paths = javaEntry.split("[/\\\\]");
		final String className = paths[paths.length - 1].substring(0 , paths[paths.length - 1].length() - 5);
		
		File dir = new File(classesDir,javaEntry).getParentFile();
		if(!dir.exists() || !dir.isDirectory()){
			 System.err.println(String.format("%s 补丁条目生成失败！由于在 %s 下没有找到任何 class 文件！"
					, javaEntry,dir.getAbsolutePath()));
			 return new String[0];
		}
		File[] files = dir.listFiles(new FileFilter() {
			
			@Override
			public boolean accept(File file) {
				if(file.getName().equals(className + ".class")){
					return true;
				}
				
				if(file.getName().startsWith(className + "$") &&
						file.getName().endsWith(".class")){
					return true;
				}
				return false;
			}
		});
		if(null == files || files.length < 1){
			 System.err.println(String.format("%s 补丁条目生成失败！由于在 %s 下没有找到任何 class 文件！"
						, javaEntry,dir.getAbsolutePath()));
				 return new String[0];
		}
		
		List<String> result = new LinkedList<String>();
		for(File file : files){
			String e = "WEB-INF/classes/";
			if(javaEntry.indexOf("/") > 0){
				e = e + javaEntry.substring(0 , javaEntry.lastIndexOf("/") + 1) + file.getName();
			}else{
				e = e + file.getName();
			}
			
			if(!result.contains(e)){
				result.add(e);
			}
		}
		return result.toArray(new String[result.size()]);
	}
	
	private String[] convertUIEntry(String uiEntry){
		if(null == uiEntry){
			throw new IllegalArgumentException(uiEntry + "不是一个合法的条目！");
		}
		uiEntry = trimSep(uiEntry);
		return new String[]{uiEntry};
	}
	
	private String trimSep(String str){
		while(str.startsWith("/") || str.startsWith("\\")){
			str = str.substring(1);
		}
		
		return str.replace("\\", "/");
	}

}
